import os from 'os';
import si from 'systeminformation';
const path = require('path');
const fs = require('fs');
import logger from './logger';
import secureStore from './secureStore';
//硬件信息
async function systemInfo() {
    logger.info("************系统（硬件）信息************");
    try {
        let sys = secureStore.getPlain("sys");
        if (sys) {
            return JSON.parse(sys);
        }
        const sysData = await si.system();
        const biosData = await si.bios();
        const baseboardData = await si.baseboard();
        sys = {
            "生产商": sysData.manufacturer,
            "型号": sysData.model,
            "BIOS厂商": biosData.vendor,
            "BIOS版本": biosData.version,
            "BIOS发布日期": biosData.releaseDate,
            "主板厂商": baseboardData.manufacturer,
            "主板型号": baseboardData.model,
            "主板版本": baseboardData.version
        };
        secureStore.setPlain("sys", JSON.stringify(sys));
        return sys;
    } catch (error) {
        logger.error(`systemInfo失败: ${error.message}`);
    }
}
//系统信息
async function osInfo() {
    logger.info("*****************系统信息*****************");
    try {
        let osinfo = secureStore.getPlain("os");
        if (osinfo) {
            return JSON.parse(osinfo);
        }
        const osData = await si.osInfo()
        osinfo = {
            "平台": osData.arch,
            "系统": osData.distro,
            "发行版": osData.logofile,
            "版本号": osData.release,
            "内核": osData.kernel,
            "主机名": osData.hostname,
            "用户目录": os.homedir()
        };
        secureStore.setPlain("os", JSON.stringify(osinfo));
        return osinfo;
    } catch (error) {
        logger.error(`osInfo失败: ${error.message}`);
    }
}
//CPU信息
async function cpuInfo() {
    logger.info("*****************CPU信息*****************");
    try {
        let cpu = secureStore.getPlain("cpu");
        if (cpu) {
            return JSON.parse(cpu);
        }
        const cpuData = await si.cpu();
        const speedData = await si.cpuCurrentSpeed();
        cpu = {
            "厂商": cpuData.manufacturer,
            "品牌": cpuData.brand,
            "频率": cpuData.speed + "GHz",
            "核心": cpuData.cores,
            "物理核心": cpuData.physicalCores,
            "处理器": cpuData.processors,
            "CPU最小频率": speedData.min,
            "CPU最大频率": speedData.max,
            "CPU平均频率": speedData.avg,
            "频率概览": speedData.cores
        };
        secureStore.setPlain("cpu", JSON.stringify(cpu));
        return cpu;
    } catch (error) {
        logger.error(`cpuInfo失败: ${error.message}`);
    }
}
//显卡信息
async function graphInfo() {
    logger.info("*****************显卡信息*****************");
    try {
        let graph = secureStore.getPlain("graph");
        if (graph) {
            return JSON.parse(graph);
        }
        const graphData = await si.graphics()
        graph = graphData.controllers.map(item => {
            return {
                "型号": item.model,
                "生产商": item.vendor,
                "显存": item.vram + "MB",
                "是否动态显存": (item.vramDynamic ? "是" : "否")
            }
        });
        secureStore.setPlain("graph", JSON.stringify(graph));
        return graph;
    } catch (error) {
        logger.error(`graphInfo失败: ${error.message}`);
    }
}
//磁盘信息
async function diskInfo() {
    logger.info("*****************磁盘信息*****************");
    try {
        let disk = secureStore.getPlain("disk");
        if (disk) {
            return JSON.parse(disk);
        }
        const diskData = await si.diskLayout()
        disk = diskData.map(item => {
            return {
                "名称": item.name,
                "类型": item.type,
                "挂载位置": item.device,
                "容量": item.size, //prettyBytes(item.size),
                "固件版本": item.firmwareRevision,
                "接口类型": item.interfaceType,
                "smart状态": item.smartStatus
            }
        });
        secureStore.setPlain("disk", JSON.stringify(disk));
        return disk;
    } catch (error) {
        logger.error(`diskInfo失败: ${error.message}`);
    }
}
//内存信息
async function memInfo() {
    logger.info("*****************内存信息*****************");
    try {
        const memData = await si.mem();
        return {
            "总内存": memData.total,//prettyBytes(memData.total),
            "已用内存": memData.used, //prettyBytes(memData.used),
            "空闲内存": memData.free, //prettyBytes(memData.free),
            "虚拟内存": memData.swaptotal, //prettyBytes(memData.swaptotal),
            "已用虚拟内存": memData.swapused, //prettyBytes(memData.swapused),
            "空闲虚拟内存": memData.swapfree //prettyBytes(memData.swapfree)
        };
    } catch (error) {
        logger.error(`memInfo失败: ${error.message}`);
    }
}
//分区信息
async function fsInfo() {
    logger.info("*****************分区信息*****************");
    try {
        const blockData = await si.blockDevices();
        const fsData = await si.fsSize();
        let data = [];
        for (let i = 0; i < blockData.length; i++) {
            let blockItem = blockData[i];
            let fsItem = fsData[i];
            let item = {
                "名称": blockItem.name,
                "类型": blockItem.type,
                "文件系统类型": blockItem.fsType,
                "挂载点": blockItem.mount
            };
            try {
                item["容量"] = blockItem.size;//prettyBytes(parseInt(blockItem.size));
                item["已使用容量"] = fsItem.used;//prettyBytes(fsItem.used);
                item["使用率"] = fsItem.use.toFixed(2) + "%";
            } catch (err) {
                item["容量"] = "";
                item["已使用容量"] = "";
                item["使用率"] = "";
            }
            item["物理类型"] = blockItem.physical;
            item["是否可拆卸"] = (blockItem.removable ? "是" : "否");
            item["协议"] = blockItem.protocol;
            data.push(item);
        }
        return data;
    } catch (error) {
        logger.error(`fsInfo失败: ${error.message}`);
    }
    return null;
}
//网卡信息
async function networkInfo() {
    logger.info("*****************网络信息*****************");
    try {
        const networkData = await si.networkInterfaces()
        const defaultNetData = await si.networkInterfaceDefault()
        return {
            "网卡": networkData.map(item => {
                return {
                    "网络连接": item.iface,
                    "网卡名称": item.ifaceName,
                    "IP地址": item.ip4,
                    "mac地址": item.mac,
                    "连接类型": item.type
                };
            }),
            "默认网络连接": defaultNetData
        };
    } catch (error) {
        logger.error(`networkInfo失败: ${error.message}`);
    }
    return null;
}
//CPU性能信息
async function loadInfo() {
    logger.info("**************性能信息**************");
    try {
        const loadData = await si.currentLoad()
        let loadCount = 1;
        let cpus = [];
        loadData.cpus.map(item => {
            cpus.push({
                ["核心" + loadCount + "负载"]: item.load.toFixed(2) + "%",
                ["核心" + loadCount + "用户负载"]: item.loadUser.toFixed(2) + "%",
                ["核心" + loadCount + "系统负载"]: item.loadSystem.toFixed(2) + "%"
            });
            loadCount++;
        });
        return {
            "平均负载": loadData.avgLoad.toFixed(2) + "%",
            "当前负载": loadData.currentLoad.toFixed(2) + "%",
            "用户负载": loadData.currentLoadUser.toFixed(2) + "%",
            "系统负载": loadData.currentLoadSystem.toFixed(2) + "%",
            "核心": cpus
        };
    } catch (error) {
        logger.error(`loadInfo失败: ${error.message}`);
    }
    return null;
}
//进程信息
async function proceInfo() {
    logger.info("**************进程信息**************");
    try {
        return await si.processes();
    } catch (error) {
        logger.error(`proceInfo失败: ${error.message}`);
    }
    return null;
}
//安装信息
async function installedAppsInfo() {
    logger.info("**************已安装软件信息**************");
    try {
        // 检查当前操作系统平台
        const platform = os.platform();
        logger.info(`当前运行平台: ${platform}`);
        // 检查 systeminformation 版本是否支持软件列表功能
        const siVersion = require('systeminformation/package.json').version;
        logger.info(`当前 systeminformation 版本: v${siVersion}`);
        // 在 v5.25.11 中没有 apps 或 softwareList 方法，使用原生命令获取
        const { exec } = require('child_process');
        const { promisify } = require('util');
        const execAsync = promisify(exec);
        if (platform === 'win32') {
            const keys = [
                'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',
                'HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',
                'HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'
            ];

            const { exec } = require('child_process');

            try {
                const results = await Promise.all(keys.map(key => queryRegistry(key, exec)));
                //logger.info(JSON.stringify(results));
                const allEntries = results.flat();
                // 额外获取UWP应用
                const uwpApps = await getUWPApps();
                logger.info(`获取到的所有应用: ${JSON.stringify(uwpApps)}`);
                // 合并所有应用
                const combinedEntries = [...allEntries, ...uwpApps];
                logger.info(`已安装软件数量: ${combinedEntries.length}`);
                // 添加更多过滤条件，排除系统组件和更新
                const softwareList = combinedEntries
                    .filter(entry => {
                        logger.info(`正在处理: ${JSON.stringify(entry)}`);
                        logger.info(`正在处理: ${entry.DisplayName}`);
                        // 基本过滤条件
                        if (!entry.DisplayName || entry.DisplayName.startsWith('{')) return false;

                        // 排除系统组件和更新
                        if (entry.SystemComponent === '1') return false;
                        if (entry.ParentKeyName) return false;
                        if (entry.WindowsInstaller === '1' && !entry.DisplayName) return false;

                        // 如果是UWP应用，特殊处理
                        if (entry.IsUWP) {
                            // UWP应用通常没有DisplayName的情况比较少见，但为了保险起见检查一下
                            return entry.DisplayName && entry.DisplayName.trim().length > 0;
                        }

                        // 排除Windows更新和补丁
                        if (entry.DisplayName.includes('Update for') && (entry.DisplayName.includes('Windows') || entry.DisplayName.includes('Microsoft'))) {
                            return false;
                        }
                        logger.info(`正在处理: ${entry.DisplayName}`);
                        // 排除一些常见的非应用条目
                        const excludePatterns = [
                            /^KB\d+/,
                            /Security Update/,
                            /Hotfix/,
                            /Service Pack/,
                            /Patch/
                        ];

                        return !excludePatterns.some(pattern => pattern.test(entry.DisplayName));
                    })
                    .map(entry => {
                        let installLocation = null;
                        if (entry.InstallLocation) {
                            installLocation = entry.InstallLocation.trim();
                        }
                        const installPath = installLocation || null;

                        // 改进可执行文件路径获取逻辑
                        let exePath = null;

                        // 1. 优先使用 DisplayIcon 指向的 .exe
                        if (entry.DisplayIcon) {
                            const iconMatch = entry.DisplayIcon.match(/^"?(.+?\.exe)"?(?:,\d+)?$/i);
                            if (iconMatch && fs.existsSync(iconMatch[1])) {
                                exePath = iconMatch[1];
                            }
                        }

                        // 2. 使用 UninstallString 中的路径
                        if (!exePath && entry.UninstallString) {
                            const uninstallMatch = entry.UninstallString.match(/"?(.+?\.exe)"?/i);
                            if (uninstallMatch && fs.existsSync(uninstallMatch[1])) {
                                exePath = uninstallMatch[1];
                            }
                        }

                        // 3. 如果没有 DisplayIcon，则尝试猜测
                        if (!exePath && installPath) {
                            exePath = findExecutable(installPath, entry.DisplayName);
                        }

                        // 4. 如果仍然没有，尝试从 QuietUninstallString 获取
                        if (!exePath && entry.QuietUninstallString) {
                            const quietMatch = entry.QuietUninstallString.match(/"?(.+?\.exe)"?/i);
                            if (quietMatch && fs.existsSync(quietMatch[1])) {
                                exePath = quietMatch[1];
                            }
                        }
                        //DisplayName,DisplayVersion,Version,VersionMajor,DisplayVersion,Manufacturer,InstallDate,InstallDateMSI,EstimatedSize,UninstallString,QuietUninstallString,InstallSource,Language
                        return {
                            name: entry.DisplayName,
                            version: entry.DisplayVersion || entry.Version || entry.VersionMajor || null,
                            publisher: entry.Publisher || entry.Manufacturer || null,
                            installDate: formatInstallDate(entry.InstallDate) || entry.InstallDateMSI || null,
                            size: parseSize(entry.EstimatedSize) || null, // EstimatedSize 单位是 KB
                            path: installPath,
                            exePath: exePath || null,
                            // 添加更多有用信息
                            uninstallString: entry.UninstallString || null,
                            quietUninstallString: entry.QuietUninstallString || null,
                            installSource: entry.InstallSource || null,
                            language: entry.Language || null
                        };
                    })
                    // 增强去重逻辑
                    .filter((item, index, self) => {
                        // 基于名称和版本进行去重
                        return self.findIndex(t =>
                            t.name === item.name &&
                            (t.version === item.version || !t.version || !item.version)
                        ) === index;
                    })
                    // 过滤掉无效条目
                    .filter(item => {
                        // 移除名称为空或无效的条目
                        if (!item.name || item.name.trim().length === 0) return false;

                        // 移除一些明显无效的条目
                        if (item.name.includes('{') && item.name.includes('}')) return false;

                        return true;
                    });
                logger.info(`获取Windows软件列表成功: ${softwareList.length} 个软件`);
                return softwareList;
            } catch (err) {
                logger.error(`获取Windows软件列表失败: ${err.message}`);
                return { error: err.message };
            }
        } else if (platform === 'darwin') {
            // macOS: 使用 system_profiler 获取软件列表
            logger.info('使用 system_profiler 获取 macOS 软件列表...');
        } else {
            // Linux: 使用 dpkg 或 rpm 获取软件列表（根据发行版）
            logger.info('使用包管理器获取 Linux 软件列表...');
        }
    } catch (err) {
        logger.error(`获取已安装软件列表时发生未知错误: ${err.message}`);
        logger.error('获取软件列表失败:');
        return [];
    }
}
// 获取UWP应用列表
async function getUWPApps() {
    return new Promise((resolve) => {
        const { exec } = require('child_process'); // 保留这一处声明
        // 使用PowerShell获取UWP应用列表
        // 移除这一行重复声明: const { exec } = require('child_process');
        //powershell -Command "Get-ChildItem -Path $location -Filter '*.exe' -File -Recurse -Depth 3 -ErrorAction SilentlyContinue"
        //powershell Remove-AppxPackage -Package "1F8B0F94.122165AE053F_3.1.13.0_x64__j2p0p5q0044a6"
        // 使用优化的PowerShell命令
        const command = `powershell -NoProfile -ExecutionPolicy Bypass -Command "Get-AppxPackage -PackageTypeFilter Main | Select-Object Name, PackageFullName, InstallLocation, Publisher, Version | ConvertTo-Json -Compress"`;

        //1.获取所有结果
        //2.检测软件目录下是否存在AppxManifest.xml，只选择存在的
        //3.检测文件内容Package>Properties>DisplayName软件名称，Package>Applications>Application[Executable="BaiduNetdiskService.exe"]软件安装地址
        // 移除这一行重复声明: const { exec } = require('child_process');

        exec(command, {
            maxBuffer: 1024 * 1024 * 20,
            encoding: 'utf8'
        }, (error, stdout, stderr) => {
            console.log('UWP Apps PowerShell command executed');
            console.log('- Error:', error);
            console.log('- Stderr:', stderr);
            //console.log('- Stdout:', stdout);
            console.log('- Stdout length:', stdout ? stdout.length : 0);

            if (error) {
                logger.error('PowerShell execution error:', error);
                resolve([]);
                return;
            }
            if (stderr) {
                logger.error(`PowerShell stderr output: ${stderr}`);
            }

            if (!stdout || stdout.trim().length === 0) {
                logger.info('PowerShell returned empty output');
                resolve([]);
                return;
            }

            try {
                const output = stdout.trim();
                let apps = [];

                // 尝试解析JSON
                try {
                    apps = JSON.parse(output);
                    console.log('- apps length:', apps ? apps.length : 0);
                } catch (e) {
                    logger.error(`JSON parse failed: ${e.message}`);
                    // 尝试处理可能的编码问题
                    try {
                        const cleanOutput = output.replace(/\r/g, '').replace(/\n/g, '').trim();
                        if (cleanOutput.startsWith('"') && cleanOutput.endsWith('"')) {
                            // 如果是被转义的JSON字符串
                            const unescaped = JSON.parse(cleanOutput);
                            apps = JSON.parse(unescaped);
                        } else {
                            apps = JSON.parse(cleanOutput);
                        }
                    } catch (e2) {
                        logger.error(`Second parse attempt failed: ${e2.message}`);
                        resolve([]);
                        return;
                    }
                }

                // 确保apps是数组格式
                if (!Array.isArray(apps)) {
                    apps = [apps];
                }

                logger.info(`Found ${apps.length} UWP packages, processing...`);

                // 进一步筛选和处理应用信息
                const processedApps = apps.filter(app => {
                    // 检查必要字段
                    if (!app.Name || !app.InstallLocation) {
                        return false;
                    }
                    // 检查InstallLocation是否存在
                    if (!fs.existsSync(app.InstallLocation)) {
                        return false;
                    }
                    const product_file_name = path.basename(app.InstallLocation);
                    if (product_file_name.toLowerCase().startsWith("microsoft") || product_file_name.toLowerCase().startsWith("windows") || product_file_name.toLowerCase().startsWith("immersivecontrolpanel")) {
                        return false;
                    }
                    // 检查AppxManifest.xml是否存在
                    const manifestPath = path.join(app.InstallLocation, 'AppxManifest.xml');
                    if (!fs.existsSync(manifestPath)) return false;

                    console.log(app.Name + "____" + app.InstallLocation);
                    return true;
                }).map(app => {
                    const manifestPath = path.join(app.InstallLocation, 'AppxManifest.xml');
                    let displayName = app.Name;
                    let exePath = null;
                    try {
                        // 读取AppxManifest.xml内容
                        const manifestContent = fs.readFileSync(manifestPath, 'utf8');
                        // 提取DisplayName
                        const displayNameMatch = manifestContent.match(/<DisplayName>(.*?)<\/DisplayName>/);
                        if (displayNameMatch && displayNameMatch[1]) {
                            const extractedName = displayNameMatch[1].trim();
                            // 忽略资源引用名称
                            if (!extractedName.startsWith('ms-resource:')) {
                                displayName = extractedName;
                            }
                        }

                        // 提取可执行文件路径
                        const appMatch = manifestContent.match(/<Application\s+[^>]*Executable\s*=\s*["']([^"']+)["'][^>]*>/i);
                        if (appMatch && appMatch[1]) {
                            const executablePath = appMatch[1];
                            // 构建完整路径
                            if (!path.isAbsolute(executablePath)) {
                                exePath = path.join(app.InstallLocation, executablePath);
                            } else {
                                exePath = executablePath;
                            }

                            // 确保.exe扩展名
                            if (!exePath.toLowerCase().endsWith('.exe')) {
                                exePath += '.exe';
                            }

                            // 验证文件存在
                            if (!fs.existsSync(exePath)) {
                                exePath = null;
                            }
                        }
                        //logger.info(`Processing UWP package: ${product_file_name}`);
                    } catch (manifestError) {
                        logger.debug(`读取或解析AppxManifest.xml失败 (${app.Name}): ${manifestError.message}`);
                    }

                    return {
                        Name: app.Name,
                        DisplayName: displayName,
                        PackageFullName: app.PackageFullName,
                        InstallLocation: app.InstallLocation,
                        Publisher: app.Publisher,
                        Version: app.Version,
                        DisplayVersion: app.Version,
                        IsUWP: true,
                        SystemComponent: '0',
                        DisplayIcon: app.Name.toLowerCase().startsWith("microsoft") || app.Name.toLowerCase().startsWith("windows") ? null : exePath
                    };
                });
                logger.info(`Successfully processed UWP apps: ${processedApps.length}`);
                resolve(processedApps.filter(app => { return app.DisplayIcon != null; }));
                //resolve([]);
            } catch (parseError) {
                logger.error(`JSON Parse Error: ${parseError.message}`);
                //logger.error(`Raw stdout:, ${stdout}`);
                resolve([]);
            }
        });
    });
}


// 读取注册表 - 修复版本
function queryRegistry(key, exec) {
    logger.info(`正在读取注册表: reg query "${key}" /s`);
    return new Promise((resolve) => {
        const command = `chcp 65001 >nul && reg query "${key}" /s`;
        exec(command, {
            maxBuffer: 1024 * 1024 * 10,
            shell: 'cmd'
        }, (error, stdout, stderr) => {
            if (error || (stderr && (stderr.includes('错误') || stderr.includes('ERROR')))) {
                var errorMessage = (error && error.message) ? error.message : stderr;
                logger.error(`读取注册表出错: ${errorMessage}`);
                resolve([]);
                return;
            }

            const lines = stdout.split('\r\n');
            const programs = [];
            let currentProgram = null;

            lines.forEach(line => {
                line = line.trim();
                if (line.startsWith('HKEY_')) {
                    if (currentProgram && Object.keys(currentProgram).length > 1) {
                        programs.push(currentProgram);
                    }
                    currentProgram = { key: line };
                } else if (line.includes('REG_SZ') || line.includes('REG_DWORD') || line.includes('REG_QWORD')) {
                    const match = line.match(/([a-zA-Z0-9_\-\.]+)\s+REG_(?:SZ|DWORD|QWORD)\s+(.*)/);
                    if (match && currentProgram) {
                        const [, name, value] = match;
                        let cleanValue = value.trim();
                        if (cleanValue.startsWith('"') && cleanValue.endsWith('"')) {
                            cleanValue = cleanValue.substring(1, cleanValue.length - 1);
                        }
                        currentProgram[name] = cleanValue;
                    }
                }
            });

            if (currentProgram && Object.keys(currentProgram).length > 1) {
                programs.push(currentProgram);
            }

            logger.info(`从 ${key} 读取到 ${programs.length} 个注册表项`);
            resolve(programs);
        });
    });
}

// 尝试从安装目录猜测主可执行文件
function findExecutable(installPath, displayName) {
    if (!installPath || !fs.existsSync(installPath)) return null;

    // 常见的可执行文件名
    const possibleNames = [
        'app.exe',
        'start.exe',
        'launch.exe',
        'run.exe',
        'main.exe'
    ];

    // 添加文件夹名+.exe和软件名去符号+.exe
    if (installPath) {
        possibleNames.push(path.basename(installPath) + '.exe');
    }
    if (displayName) {
        possibleNames.push(displayName.replace(/[^\w]/g, '') + '.exe');
    }

    // 去重
    const uniqueNames = [...new Set(possibleNames)];

    // 先检查顶级目录
    for (let name of uniqueNames) {
        const exePath = path.join(installPath, name);
        if (fs.existsSync(exePath)) return exePath;
    }

    // 再递归查找第一层子目录
    try {
        const files = fs.readdirSync(installPath);
        for (let file of files) {
            const fullPath = path.join(installPath, file);
            if (file.toLowerCase().endsWith('.exe') && fs.statSync(fullPath).isFile()) {
                return fullPath;
            }
        }
    } catch (e) { }

    return null;
}

// 格式化注册表日期（YYYYMMDD -> YYYY-MM-DD）
function formatInstallDate(rawDate) {
    logger.debug(`格式化注册表日期：${rawDate}`);
    if (!rawDate || rawDate.length !== 8) return null;
    const year = rawDate.substr(0, 4);
    const month = rawDate.substr(4, 2);
    const day = rawDate.substr(6, 2);
    return `${year}-${month}-${day}`;
}

// 获取软件大小（KB -> 字节）
// 获取软件大小（KB -> 字节）
function parseSize(sizeStr) {
    logger.debug(`解析软件大小：${sizeStr}`);
    if (!sizeStr) return null;

    try {
        // 尝试解析为整数（自动识别进制）
        const num = parseInt(String(sizeStr).trim());

        // 检查是否为有效数字
        if (isNaN(num)) return null;

        // 返回字节大小（注册表中的EstimatedSize单位是KB）
        return Math.round(num * 1024);
    } catch (error) {
        logger.warn(`解析软件大小时出错: ${error.message}, 原始值: ${sizeStr}`);
        return null;
    }
}
export default {
    systemInfo, cpuInfo, memInfo, graphInfo, osInfo, diskInfo, fsInfo, networkInfo, loadInfo, proceInfo, installedAppsInfo
};